#ifndef DRIVER_VBE_H
#define DRIVER_VBE_H

#include <lib/type.h>
#include <arch/pymem.h>
#include <os/driver.h>
#include <arch/page.h>
#include <arch/address.h>

#define DEVICE_NAME "video"
#define DRIVER_NAME "vbe-graph"
#define DRIVER_VERSION "0.1"

#define VBE_INFO_ADDR 0x00001100
#define VBE_MODE_INFO_ADDR 0x00001300

#define VBE_INFO_BASE (KERNEL_PYBASE2VBASE(VBE_INFO_ADDR))
#define VBE_MODE_INFO_BASE (KERNEL_PYBASE2VBASE(VBE_MODE_INFO_ADDR))

struct vbe_info_block
{
    uint8_t VbeSignature[4];      // VBE signature: VESA
    uint16_t VbeVersion;          // VBE version 0x30
    uint32_t OemStringPtr;        // OEM string far point
    uint8_t Capabilites[4];       // capabilities filed
    uint32_t VideoModePtr;        // VBE mode ptr
    uint16_t TotolMemory;         // number of 64KB memory block
    uint16_t OemSoftwareRevision; // VBE software revision
    uint32_t OemVendorNamePtr;    // VBE far ptr of vendor name string
    uint32_t OemProductNamePtr;   // VBE far pth of product name string
    uint8_t Reserved[222];        // reserved for VBE implement area
    uint8_t OemData[256];         // data area of oem string
} __attribute__((packed));

struct vbe_mode_info_block
{
    uint16_t ModeAttribute;    // mode attribute
    uint8_t WinAAttribute;     // windows A attribute
    uint8_t WinBAttribute;     // windows B attribute
    uint16_t WinGranulaity;    // windows granulaity
    uint16_t WinSize;          // size of windows
    uint16_t WinASegment;      // windows A segment
    uint16_t WinBSegment;      // Windows B segment
    uint32_t WinFuncPtr;       // real mode windows func ptr
    uint16_t BytesPerScanline; // bytes of scanline
    uint16_t XResolution;      // horizontal resoultion in pixel or charset
    uint16_t YResolution;      // vertical resoultion in pixel or charset
    /* Mandatory information for VBE1.2 and above */
    uint8_t XCharSize;           /* character cell width in pixels */
    uint8_t YCharSize;           /* character cell height in pixels */
    uint8_t NumberOfPlanes;      /* number of banks */
    uint8_t BitsPerPixel;        /* bits per pixel */
    uint8_t NumberOfBanks;       /* number of banks */
    uint8_t MemoryModel;         /* memory model type */
    uint8_t BankSize;            /* bank size in KB */
    uint8_t NumberOfImagePages;  /* number of images */
    uint8_t Reserved0;           /* reserved for page function: 1 */
    uint8_t RedMaskSize;         /* size of direct color red mask in bits */
    uint8_t RedFieldPosition;    /* bit position of lsb of red mask */
    uint8_t GreenMaskSize;       /* size of direct color green mask in bits */
    uint8_t GreenFieldPosition;  /* bit position of lsb of green mask */
    uint8_t BlueMaskSize;        /* size of direct color blue mask in bits */
    uint8_t BlueFieldPosition;   /* bit position of lsb of blue mask */
    uint8_t RsvdMaskSize;        /* size of direct color reserved mask in bits */
    uint8_t RsvdFieldPosition;   /* bit position of lsb of reserved mask */
    uint8_t DirectColorModeInfo; /* direct color mode attributes */

    /* Mandatory information for VBE2.0 and above */
    uint32_t phyBasePtr; /* physical address for flat memory frame buffer */
    uint32_t reserved1;  /* reserved-always set to 0 */
    uint16_t reserved2;  /* reserved-always set to 0 */
    /* Mandatory information for VBE3.0 and above */
    uint16_t linebytesPerScanLine; /* bytes per scan line for linear modes */
    uint8_t bnkNumberOfImagePages; /* number of images for banked modes */
    uint8_t linNumberOfImagePages; /* number of images for linear modes */
    uint8_t linRedMaskSize;        /* size of direct color red mask(linear modes) */
    uint8_t linRedFieldPosition;   /* bit position of lsb of red mask(linear modes) */
    uint8_t linGreenMaskSize;      /* size of direct color green mask(linear modes) */
    uint8_t linGreenFieldPosition; /* bit position of lsb of green mask(linear modes) */
    uint8_t linBlueMaskSize;       /* size of direct color blue mask(linear modes) */
    uint8_t linBlueFieldPosition;  /* bit position of lsb of blue mask(linear modes) */
    uint8_t linRsvdMaskSize;       /* size of direct color reserved mask(linear modes) */
    uint8_t linRsvdFieldPosition;  /* bit position of lsb of reserved mask(linear modes) */
    uint32_t maxPixelClock;        /* maximum pixel clock (in HZ) for graphics mode */
    uint8_t reserved3[189];        /* remainder of ModeInfoBlock */
} __attribute__((packed));

typedef struct vbe_info_block vbe_info_block_t;
typedef struct vbe_mode_info_block vbe_mode_info_block_t;

typedef struct
{
    device_object_t *device;
    vbe_mode_info_block_t *mode_info;
    vbe_info_block_t *vbe_info;
    uint8_t *virbase;
} device_extension_t;

#endif